Step 1 - Pan the map

Use the pan manipulator to enable users to move nodes in your Kanzi application. The pan manipulator is one of the input manipulators you can use to add gesture recognition to nodes in your Kanzi application. The pan gesture tracks the position of the pointer that moves on the device screen to calculate the amount by which to move a node.

In this step of the tutorial you use the pan manipulator to enable moving the map.

Assets for the tutorial

The starting point of this tutorial is stored in the <KanziWorkspace>/Tutorials/Pan zoom tap/Start directory.

The <KanziWorkspace>/Tutorials/Pan zoom tap/Completed directory contains the completed project of this tutorial.

The starting point project contains the content you need to complete this tutorial:

Pan the map

In this section you create and use a pan manipulator to move the map when the user puts the pointer down on the map and moves the pointer.

To pan the map:

  1. In Kanzi Studio open the project stored in <KanziWorkspace>/Tutorials/Pan zoom tap/Start/Tool_project.
  2. In the Project select the RootPage > Map node, in the Properties add the Hit Testable property, and enable it.
    When you enable this property you enable the user to pick a node.
  3. Select File > Export > Export KZB.
    Kanzi Studio creates the kzb file and configuration files from your Kanzi Studio project. Kanzi Studio stores the exported files in the <ProjectName>/Application/bin directory or the location you specify in the Binary Export Directory property in Project > Properties. The kzb file contains all nodes and resources from your Kanzi Studio project, except the resources you mark in a localization table as locale packs.
    When you run your Kanzi application from Visual Studio, your application loads the kzb file and configuration files.
  4. In Visual Studio open the Pan_zoom_tap.sln solution stored in Pan zoom tap/Start/Application/configs/platforms/win32.
    If you open the tutorial solution in Visual Studio 2017, when asked to retarget the project to the latest Microsoft toolset, click Cancel.
    TIP

    To open the directory of a Kanzi Studio project from Kanzi Studio, select File > Open in Windows Explorer.

  5. In Visual Studio open the pan_zoom_tap.cpp file and in the PanZoomTap class, after the public section, define the handler for the PanManipulator::MovedMessage message:
    private:
    
        // Define the handler for the PanManipulator::MovedMessage message from 2D nodes
        // that have an input manipulator which generates pan messages.
        // This handler translates a 2D node for the amount of the pan gesture.
        void onPanMoved(PanManipulator::MovedMessageArguments& messageArguments)
        {
            // Get from the message arguments the node that the user pans.
            Node2DSharedPtr mapNode = dynamic_pointer_cast<Node2D>(messageArguments.getSource());
    
            // Get the distance in pixels for which the pan progressed
            // since the last message in the pan gesture sequence.
            Vector2 translationDelta = messageArguments.getDelta();
    
            // Get the Render Transformation property of the Map node.
            SRTValue2D mapNodeSRT = mapNode->getRenderTransformation();
    
            // Get the current translation of the Map node.
            Vector2 translation = mapNodeSRT.getTranslation();
    
            // Apply the translation from the pan message.
            Vector2 translationTarget = translation - translationDelta;
    
            // Get the parent node of the Map node.
            Node2D* containerNode = dynamic_cast<Node2D*>(mapNode->getParent());
    
            // Get the size of the parent node.
            Vector2 containerSize = containerNode->getActualSize();
    
            // Get the Render Transformation property Scale property field of the Map node.
            Vector2 mapScale = mapNodeSRT.getScale();
    
            // Calculate the scaled size of the Map node.
            Vector2 mapSizeScaled = componentWiseMultiply(mapNode->getActualSize(), mapScale);
    
            // Do not pan outside the boundaries of the Map node.
            // When calculating the boundaries, take into account the current scale of the map.
            if (mapScale.getX() >= 1.0f) 
            {
                translationTarget = componentWiseMax(componentWiseMin(translationTarget, (mapSizeScaled - containerSize) / 2), (containerSize - mapSizeScaled) / 2);
            }
            else if (mapScale.getX() < 1.0f)
            {
                translationTarget = componentWiseMin(componentWiseMax(translationTarget, (containerSize - mapSizeScaled) / 2), (mapSizeScaled - containerSize) / 2);
            }
    
            // Set the new translation.
            mapNodeSRT.setTranslation(translationTarget);
    
            // Apply the new transform to the Map node.
            mapNode->setRenderTransformation(mapNodeSRT);
        }
  6. In the onProjectLoaded() function create a PanManipulator manipulator and subscribe to its messages at the Map node:
        virtual void onProjectLoaded() KZ_OVERRIDE
        {
            // Pointer to the domain.
            Domain* domain = getDomain();
    
            // Get the Screen node.
            ScreenSharedPtr screen = getScreen();
    
            // Get the Map node using its alias.
            Node2DSharedPtr mapNode = screen->lookupNode<Node2D>("#Map");
    
            // Create an input manipulator that generates pan messages.
            PanManipulatorSharedPtr panManipulator = PanManipulator::create(domain);
    
            // Set the threshold in pixels on the horizontal and vertical axis that the pointer
            // must move before the input manipulator recognizes the pan gesture.
            panManipulator->setRecognitionThreshold(Vector2(10.0f, 10.0f));
    
            // Add the input manipulator to the Map node.
            mapNode->addInputManipulator(panManipulator);
    
            // Subscribe to the PanManipulator::MovedMessage message at the Map node.
            // The PanManipulator generates this message when the user moves the pointer on the horizontal or
            // vertical axis more than the recognition threshold and when the pointer moves between updates.
            mapNode->addMessageHandler(PanManipulator::MovedMessage, bind(&PanZoomTap::onPanMoved, this, placeholders::_1));
        }
  7. In Visual Studio select one of the solution configurations for your version of Visual Studio and run your application.
    For example, if you are still developing your application, select the GL_vs2015_Debug configuration. If you want to create a production version of your Kanzi application, select one of the available release configurations.

    In the application click and drag the map to pan it.


< INTRODUCTION
NEXT STEP >

See also

To learn more about handling user input in Kanzi, see Handling user input.

To learn more about the pan manipulator, see Using the pan manipulator.

To learn more about aliases in Kanzi, see Using aliases.